﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Threading;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Diagnostics;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;
using CloudVideoRenderer;

namespace CloudVideoRendererWorkerRole
{
    public class WorkerRole : RoleEntryPoint
    {
        private readonly string wadConnectionString = "Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString";

        public override void Run()
        {
            LocalResource imageTempStoreResource = RoleEnvironment.GetLocalResource("ImageTempStore");
            Trace.WriteLine("CloudVideoRenderer entry point called" + ": " + Environment.GetEnvironmentVariable("RoleRoot") + @"\\approot\bmp2avi.exe" + ": " + imageTempStoreResource.RootPath + @"\\bmp2avi.exe", "Information");
            System.IO.File.Copy(Environment.GetEnvironmentVariable("RoleRoot") + @"\\approot\bmp2avi.exe", imageTempStoreResource.RootPath + @"\\bmp2avi.exe");


            while (true)
            {
                Trace.WriteLine("Working", "Information");

                //Pick message from queue

                CloudQueueClient queueClient = new CloudQueueClient("http://[storage account name].queue.core.windows.net/", new StorageCredentialsAccountAndKey("[storage account name]", "[storage access key]"));
                CloudQueue renderJobQueue = queueClient.GetQueueReference("renderjobqueue");
                renderJobQueue.CreateIfNotExist();
                if (renderJobQueue == null)
                {
                    //There is no queue for this instance to monitor.
                    //Wait and retry till it appears.
                    Thread.Sleep(1000);
                    continue;
                }

                CloudQueueMessage message = renderJobQueue.GetMessage();

                if (message == null)
                {
                    Trace.WriteLine("Sleeping 5000ms", "Notifications");

                    Thread.Sleep(5000);
                    continue;
                }

                CloudVideoRenderJob cloudVideoRenderJob = MessageSerializer.DeserializeMessage<CloudVideoRenderJob>(message.AsString);


                Trace.WriteLine("Message deserialized", "Notifications");

                //Pass command
                CloudVideoRenderer.CloudVideoRenderer renderer = new CloudVideoRenderer.CloudVideoRenderer();
                renderer.RenderVideo(cloudVideoRenderJob.CameraID, imageTempStoreResource.RootPath, cloudVideoRenderJob.FrameRate);

                try
                {
                    renderJobQueue.DeleteMessage(message);
                }
                catch { }
            }
        }

        /// <summary> 
        /// Performs initial configurarion for Windows Azure Diagnostics for the instance.
        /// </summary> 
        private void ConfigureDiagnosticMonitor()
        {
            DiagnosticMonitorConfiguration diagnosticMonitorConfiguration = DiagnosticMonitor.GetDefaultInitialConfiguration();

            diagnosticMonitorConfiguration.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(1d);
            diagnosticMonitorConfiguration.Directories.BufferQuotaInMB = 100;

            diagnosticMonitorConfiguration.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1d);
            diagnosticMonitorConfiguration.Logs.ScheduledTransferLogLevelFilter = LogLevel.Verbose;

            diagnosticMonitorConfiguration.WindowsEventLog.DataSources.Add("Application!*");
            diagnosticMonitorConfiguration.WindowsEventLog.DataSources.Add("System!*");
            diagnosticMonitorConfiguration.WindowsEventLog.ScheduledTransferPeriod = TimeSpan.FromMinutes(1d);

            PerformanceCounterConfiguration performanceCounterConfiguration = new PerformanceCounterConfiguration();
            performanceCounterConfiguration.CounterSpecifier = @"\Processor(_Total)\% Processor Time";
            performanceCounterConfiguration.SampleRate = System.TimeSpan.FromSeconds(10d);
            diagnosticMonitorConfiguration.PerformanceCounters.DataSources.Add(performanceCounterConfiguration);
            diagnosticMonitorConfiguration.PerformanceCounters.ScheduledTransferPeriod = TimeSpan.FromMinutes(1d);

           // DiagnosticMonitor.Start(wadConnectionString, diagnosticMonitorConfiguration);
        }

        public override bool OnStart()
        {
            ServicePointManager.DefaultConnectionLimit = 12;

            System.Diagnostics.Trace.Listeners.Add(new Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener());
            System.Diagnostics.Trace.TraceInformation("In OnStart");

            this.ConfigureDiagnosticMonitor();

            // For information on handling configuration changes
            // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
            RoleEnvironment.Changing += RoleEnvironmentChanging;


            return base.OnStart();
        }

        private void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e)
        {
            // If a configuration setting is changing
            if (e.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange))
            {
                // Set e.Cancel to true to restart this role instance
                e.Cancel = true;
            }
        }

    }
}
